package libcontrol.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import libcontrol.model.Reserva.Estado;

/**
 *
 * @author marco
 */
@Entity
public class Usuario implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    @ManyToOne
    Perfil perfil;
    @OneToMany(mappedBy = "usuario", cascade = CascadeType.ALL)
    private List<Reserva> reservas;
    @OneToMany(mappedBy = "usuario", cascade = CascadeType.ALL)
    private List<Emprestimo> emprestimos;
    @OneToMany(mappedBy = "usuario", cascade = CascadeType.ALL)
    private List<Debito> debitos;
    private String nome;
    @Column(unique = true)
    private String cpf;
    @Column(unique = true)
    private String login;
    private String senha;
    private String cidade;
    private String uf;
    private String cep;
    private String logradouro;
    private String numero;
    private String complemento;
    private String telefone;
    @Column(unique = true)
    private String email;

    public boolean hasDebitosPendentes() {
        return !getDebitosPendentes().isEmpty();
    }

    public List<Debito> getDebitosPendentes() {
        ArrayList<Debito> debitosPendentes = new ArrayList<>();
        for (Debito debito : debitos) {
            if (debito.isAtivo()) {
                debitosPendentes.add(debito);
            }
        }
        return debitosPendentes;
    }

    public boolean hasDevolucoesAtrasadas() {
        for (Emprestimo emprestimo : getEmprestimosAtivos()) {
            if (emprestimo.isAtrasado()) {
                return true;
            }
        }
        return false;
    }

    public boolean atingiuMaxEmprestimos() {
        return !(perfil.getMaxEmprestimos() > getEmprestimosAtivos().size());
    }

    public boolean isAptoParaEmprestar() {
        return !hasDebitosPendentes() && !atingiuMaxEmprestimos() && !hasDevolucoesAtrasadas();
    }

    public List<Debito> getDebitos() {
        return debitos;
    }

    public void setDebitos(List<Debito> debitos) {
        this.debitos = debitos;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getId() {
        return id;
    }

    public Perfil getPerfil() {
        return perfil;
    }

    public List<Reserva> getReservas() {
        return reservas;
    }

    public boolean hasReserva(Obra obra) {
        for (Reserva reserva : getReservasAtivas()) {
            if (reserva.getObra().equals(obra)) {
                return true;
            }
        }
        return false;
    }

    public List<Reserva> getReservasAtivas() {
        ArrayList<Reserva> reservasAtivas = new ArrayList<>();
        for (Reserva reserva : reservas) {
            if (reserva.getEstado().equals(Estado.ATIVA)) {
                reservasAtivas.add(reserva);
            }
        }
        return reservasAtivas;
    }

    public void setReservas(List<Reserva> reservas) {
        this.reservas = reservas;
    }

    public List<Emprestimo> getEmprestimos() {
        return emprestimos;
    }

    public List<Emprestimo> getEmprestimosAtivos() {
        List<Emprestimo> emprestimosAtivos = new ArrayList<>();
        for (Emprestimo emprestimo : emprestimos) {
            if (emprestimo.isAtivo()) {
                emprestimosAtivos.add(emprestimo);
            }
        }
        return emprestimosAtivos;
    }

    public void setEmprestimos(List<Emprestimo> emprestimos) {
        this.emprestimos = emprestimos;
    }

    public void setPerfil(Perfil perfil) {
        this.perfil = perfil;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getCpf() {
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }

    public String getCidade() {
        return cidade;
    }

    public void setCidade(String cidade) {
        this.cidade = cidade;
    }

    public String getUf() {
        return uf;
    }

    public void setUf(String uf) {
        this.uf = uf;
    }

    public String getLogradouro() {
        return logradouro;
    }

    public void setLogradouro(String logradouro) {
        this.logradouro = logradouro;
    }

    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }

    public String getComplemento() {
        return complemento;
    }

    public void setComplemento(String complemento) {
        this.complemento = complemento;
    }

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Usuario)) {
            return false;
        }
        Usuario other = (Usuario) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return perfil + " " + nome;
    }

    public boolean hasEmprestimos() {
        for (Emprestimo emprestimo : emprestimos) {
            if (emprestimo.isAtivo()) {
                return true;
            }
        }
        return false;
    }

    public Reserva getReservaAtiva(Obra obra) {
        for (Reserva reserva : getReservasAtivas()) {
            if (reserva.getObra().getId() == obra.getId()) {
                return reserva;
            }
        }
        return null;
    }

    public boolean hasEmprestimo(Obra obra) {
        for (Emprestimo emprestimo : getEmprestimosAtivos()) {
            if (emprestimo.getExemplar().getObra().getId() == obra.getId()) {
                return true;
            }
        }
        return false;
    }
}
